package com.jiyongjun.component.core.model;

import com.jiyongjun.component.annotation.ApiMethodMetadata;
import com.jiyongjun.component.enums.LogConstant;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
import lombok.experimental.FieldNameConstants;
import lombok.extern.slf4j.Slf4j;

import javax.validation.constraints.NotNull;
import java.util.Map;

import static com.jiyongjun.component.enums.LogConstant.LOG_EXCEPTION_KEYWORD;

/**
 * <h2></h2>
 * <h3>描述：</h3>
 *
 * @author yongjun.jyj
 * @since 2022/7/14 19:20
 */
@Getter
@Setter
@Accessors(chain = true)
@Slf4j
@FieldNameConstants
public class DubboLogContext extends BaseLogContext<DubboLogContext>{
    /** 调用是否超时 */
    private Boolean timeout = false;
    /** {@link ApiMethodMetadata#ext()} */
    private String ext;

    public static final DubboLogContext NO_OP_CONTEXT = new DubboLogContext(null, null);
    /**
     * @param apiUniqueName 接口名
     * @param logThreadLocal 日志上下文
     */
    protected DubboLogContext(String apiUniqueName, ThreadLocal<Map<String, BaseLogContext<?>>> logThreadLocal) {
        super(apiUniqueName, logThreadLocal);
    }

    public @NotNull static DubboLogContext getLogContext(String apiName, boolean createIfAbsent) {
        try {
            return (DubboLogContext) LogContext.getLogContext(DubboLogContext.class, apiName, createIfAbsent);
        } catch (Exception e) {
            log.warn("{}|获取dubbo日志上下文异常|apiName={},msg={}", LOG_EXCEPTION_KEYWORD, apiName, e.getMessage(), e);
            return NO_OP_CONTEXT;
        }
    }

    public void drop() {
        if (this.getApiUniqueName() == null) {
            return;
        }

        try {
            Map<String, BaseLogContext<?>> logVoMap = this.getLogThreadLocal().get();
            logVoMap.remove(this.getApiUniqueName());
            if (logVoMap.isEmpty()) {
                this.getLogThreadLocal().remove();
            }
        } catch (Throwable throwable) {
            log.warn("{}|销毁日志异常|exception|msg={}", LOG_EXCEPTION_KEYWORD, throwable.getMessage(), throwable);
        }
    }


}
